package com.leyou.item.service.impl;

import static com.leyou.commons.constants.MQConstants.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.commons.dto.PageDTO;
import com.leyou.commons.exception.LyException;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {
    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private SpuDetailService spuDetailService;
    @Autowired
    private  SpuService spuService;

    @Autowired
    private AmqpTemplate amqpTemplate;
    @Override
    /**
     * 商品集合分页查询
     */
    public PageDTO<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, Integer categoryId, Integer brandId, Integer id) {
        page =  Math.max(page,1);
        rows = Math.min(rows, 5);
        //根据条件分页查询商品
        Page<Spu> result = query()
                .eq(saleable != null, "saleable", saleable)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(brandId != null, "brand_id", brandId)
                .eq(id != null, "id", id)
                .page(new Page<>(page, rows));
        //转换DTO
        List<SpuDTO> spuDTOS = SpuDTO.convertEntityList(result.getRecords());
        // 查询spu的分类和品牌的名称
        for (SpuDTO spuDTO : spuDTOS) {
            handleCategoryAndBrandName(spuDTO);
        }
        return new PageDTO<>(result.getTotal(),result.getPages(),spuDTOS);
    }

    private void handleCategoryAndBrandName(SpuDTO spuDTO) {
    //根据品牌id查询品牌
        Brand brand = brandService.getById(spuDTO.getBrandId());
        spuDTO.setBrandName(brand.getName());
        //根据三级类目查询类名称
        List<Category> categories = categoryService.listByIds(spuDTO.getCategoryIds());
        String names = categories.stream().map(Category::getName).collect(Collectors.joining("/"));
        spuDTO.setCategoryName(names);
    }

    @Override
    @Transactional
    /**
     * todo
     * 修改商品是否上下架
     */
    public void updateSpuSaleable(long id, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        boolean success = updateById(spu);
        if (!success) {
            throw new LyException(500, "更新失败");
        }
        // 2.更新sku 特殊属性也需要下架
        success = skuService.update().eq("spu_id",id).set("saleable",saleable).update();
        if (!success) {
            throw new LyException(500, "更新失败");
        }

        // 3.发送MQ消息
        String routingKey = saleable ? RoutingKeyConstants.ITEM_UP_KEY : RoutingKeyConstants.ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ExchangeConstants.ITEM_EXCHANGE_NAME, routingKey, id);
    }

    @Override
    @Transactional
    /**
     * 新增商品
     */
    public void SaveGoods(SpuDTO spuDTO) {
        //新增spu
        Spu spu = spuDTO.toEntity(Spu.class);
        spu.setSaleable(true);
        if(!save(spu)){
            throw new LyException(500,"新增spu失败");
        }
        //新增spudetail
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        if(!spuDetailService.save(spuDetail)){
            throw new LyException(500,"新增spudetail失败");
        }
        //新增sku
        List<SkuDTO> skuDTOS = spuDTO.getSkus();
        List<Sku> skuList = skuDTOS.stream().map(skuDTO ->
                {
                    Sku sku = skuDTO.toEntity(Sku.class);
                    sku.setSaleable(true);
                    sku.setSpuId(spu.getId());
                    return sku;
                }).collect(Collectors.toList());
        skuService.saveBatch(skuList);
    }

    @Override
    /**todo
     * 根据商品id查询商品 并传入规格参数
     */
    public SpuDTO queryGoodsByid(Integer spuId) {
        //查询spu
        Spu spu = spuService.getById(spuId);
        if(spu==null){
            throw new LyException(400,"商品信息不存在");
        }
        SpuDTO spuDTO = new SpuDTO(spu);

        //查询spuDetail
        SpuDetail spuDetail = spuDetailService.getById(spuId);
        if(spuDetail==null){
            throw new LyException(400,"商品信息不存在");
        }
        SpuDetailDTO spuDetailDTO = new SpuDetailDTO(spuDetail);
        spuDTO.setSpuDetail(spuDetailDTO);

        //查询sku
        List<Sku> skus = skuService.query().eq("spu_id", spuId).list();
        //吧sku转换成skuDTO
       if(skus.size()==0){
           throw new LyException(400,"商品信息不存在");
       }
        List<SkuDTO> skuDTOS = SkuDTO.convertEntityList(skus);
       spuDTO.setSkus(skuDTOS);

       //准备商品分类和品牌名称
        handleCategoryAndBrandName(spuDTO);
        return spuDTO;
    }

    @Override
    @Transactional
    /**
     * todo
     * 修改商品信息 以及其包含的规格参数
     */
    public void updateGoods(SpuDTO spuDTO) {
        Long spuId = spuDTO.getId();
        //判断spuid不为空
        if(spuId!=null) {
            if (spuService.updateById(spuDTO.toEntity(Spu.class))) {
                log.info("spu修改成功");
            } else {
                log.info("spu修改失败");
                throw new LyException(500, "修改失败");
            }
        }

        //获取spudetail
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        //判断spudetail不为空则修改
            if(spuDetailDTO!=null && spuDetailDTO.getSpuId()!=null){
                if(spuDetailService.updateById(spuDetailDTO.toEntity(SpuDetail.class))){
                log.info("spudetail修改成功");
                }else {
                log.info("spudetail修改失败");
                throw new LyException(500,"修改失败");
                }
            }

            //获取sku
            List<SkuDTO> skus = spuDTO.getSkus();
            //判断sku是否有值
            if(skus.size()==0){
                return;
            }
            //遍历得到每个skoDTO
            for (SkuDTO skuDTO : skus) {
                //判断skuDTO的id是否有值，有值则为修改或者删除,无值则为新增
               if(skuDTO.getId()!=null){
                   //saleable为空则表示是修改，不为空则是删除
                   if(skuDTO.getSaleable()==null){
                    skuService.updateById(skuDTO.toEntity(Sku.class));
                    log.info("sku修改成功");
                   }else{
                       skuService.removeById(skuDTO.getId());
                       log.info("sku删除成功");
                   }
               }else {
                   skuService.save(skuDTO.toEntity(Sku.class));
               }
            }
    }
}
